#include "stdafx.h"
#include "GameObjectCache.h"
#include "Game.h"


GameObjectCache::GameObjectCache()
{
}


GameObjectCache::~GameObjectCache()
{
	std::for_each(_gameObjects.begin(), _gameObjects.end(), GameObjectDeallocator());
}

void GameObjectCache::Add(std::string name, VisibleGameObject* gameObject)
{
	_gameObjects.insert(std::pair<std::string, VisibleGameObject*>(name, gameObject));
	CollidableObject* collidableObject = dynamic_cast<CollidableObject*>(gameObject);
	if (collidableObject != NULL)
		_collidableObjects.insert(std::pair<std::string, CollidableObject*>(name, collidableObject));
}

void GameObjectCache::Remove(std::string name)
{
	std::map<std::string, VisibleGameObject*>::iterator results = _gameObjects.find(name);
	if (results != _gameObjects.end())
	{
		delete results->second;
		_gameObjects.erase(results);
	}
}

VisibleGameObject* GameObjectCache::Get(std::string name) const
{
	std::map<std::string, VisibleGameObject*>::const_iterator results = _gameObjects.find(name);
	if (results == _gameObjects.end())
	{
		return NULL;
	}
	return results->second;
}

int GameObjectCache::GetObjectCount() const
{
	return _gameObjects.size();
}

void GameObjectCache::DrawAll(sf::RenderWindow& renderWindow)
{
	std::map<std::string, VisibleGameObject*>::const_iterator itr = _gameObjects.begin();
	while (itr != _gameObjects.end())
	{
		itr->second->Draw(renderWindow);
		itr++;
	}
}

void GameObjectCache::UpdateAll()
{
	std::map<std::string, VisibleGameObject*>::const_iterator itr = _gameObjects.begin();

	float timeDelta = _clock.restart().asSeconds();

	while (itr != _gameObjects.end())
	{
		itr->second->Update(timeDelta);
		itr++;
	}
}
void GameObjectCache::Pause(bool isPaused)
{
	std::map<std::string, VisibleGameObject*>::const_iterator itr = _gameObjects.begin();

	while (itr != _gameObjects.end())
	{
		itr->second->Pause(isPaused);
		itr++;
	}
	_clock.restart();

}

void GameObjectCache::CheckCollisions()
{
	std::map<std::string, CollidableObject*>::iterator itr = _collidableObjects.begin();
	while (itr != _collidableObjects.end())
	{
		std::map<std::string, CollidableObject*>::iterator innerItr = std::next(itr, 1);
		while(innerItr != _collidableObjects.end())
		{
			if (itr->second->GetBoundingRect().intersects(innerItr->second->GetBoundingRect()))
			{
				itr->second->collideWith(innerItr->second);
				innerItr->second->collideWith(itr->second);
			}
			innerItr++;
		}
		itr++;
	}
}